package com.yjh.server.controller.miniapp;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yjh.pojo.dto.ReserveDto;
import com.yjh.pojo.entity.*;
import com.yjh.pojo.vo.R;
import com.yjh.pojo.vo.ReserveVo;
import com.yjh.server.service.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/mini/reserve")
public class MiniReservationController {
    @Autowired
    private ReservationTimeService reservationTimeService;
    @Autowired
    private UserService userService;
    @Autowired
    private ReserveTimeRelationService reserveTimeRelationService;
    @Autowired
    private ReservationMainService reservationMainService;
    @Autowired
    private CourtInfoService courtInfoService;

    /**
     * 查询指定球场指定日期的可预约时段
     * @param courtId 球场ID（必填）
     * @param reserveDate 预约日期（格式：yyyy-MM-dd，必填）
     * @return 可预约时段列表（timeId + timeSlot 核心信息）
     */
    @GetMapping("/inAvailableTime")
    public R<List<ReservationTime>> getInAvailableSlots(
            @RequestParam Integer courtId,
            @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate reserveDate) {

        //  查询已被预约的时间段
        List<ReservationTime> bookedSlots = reservationTimeService.getInAvailableSlots(courtId, reserveDate);

        //  用Set存储，自动去重（基于timeId）
        Set<ReservationTime> unavailableSlots = new HashSet<>();
        unavailableSlots.addAll(bookedSlots);

        //  若预约的日期是今天，要去除现在之前的时间段预约
        LocalDate localDate = LocalDate.now();
        if(reserveDate.equals(localDate)){
            //  查询所有时间段
            List<ReservationTime> allTimeSlots = reservationTimeService.list();

            //  获取当前时间之前的时间段
            int currentHour = LocalTime.now().getHour();
            List<ReservationTime> pastTimeSlots = allTimeSlots.stream()
                    .filter(item -> item.getStartHour() <= currentHour)
                    .collect(Collectors.toList());
            unavailableSlots.addAll(pastTimeSlots);
        }

        return R.success(new ArrayList<>(unavailableSlots));
    }

    @GetMapping("/timeSlots")
    public R<List<ReservationTime>> getTimeSlots(){
        List<ReservationTime> list = reservationTimeService.list();
        return R.success(list);
    }

    @PostMapping("/addReservation")
    @Transactional
    public R<Map<String,Object>> addReservation(@RequestBody ReserveDto reserveDto){
        System.out.println(reserveDto);
        if (reserveDto.getUserId() == null) {
            return R.error("用户ID不能为空");
        }
//        更新用户表
        User user=new User();
        user.setUserId(reserveDto.getUserId());
        user.setRealname(reserveDto.getRealname());
        user.setPhone(reserveDto.getPhone());
        userService.updateById(user);  //MP会自动忽略实体中为null的字段
//        在预约表插入预约数据
        reservationMainService.save(reserveDto);

//        把预约时间段插入中间表
        for(Integer i: reserveDto.getTimeIds()){
            ReserveTimeRelation reserveTimeRelation = new ReserveTimeRelation();
            reserveTimeRelation.setReserveId(reserveDto.getReserveId());
            reserveTimeRelation.setTimeId(i);
            reserveTimeRelationService.save(reserveTimeRelation);
        }

//        System.out.println(reserveDto);
        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("reserveId",reserveDto.getReserveId());
        return R.success(hashMap);
    }

    @GetMapping("/getReservation")
    public R<List> getReservation(){
        List<ReservationMain> list = reservationMainService.list();

        List<ReserveVo> reserveList = list.stream().map(item -> {
//            预约信息
            ReserveVo reserveVo=new ReserveVo();
            BeanUtils.copyProperties(item,reserveVo);
//            球场信息
            CourtInfo courtInfo = courtInfoService.getById(item.getCourtId());
            reserveVo.setCourtName(courtInfo.getCourtName());
            reserveVo.setCourtImg(courtInfo.getCourtImg());
//            预约时间
            String minMaxTime = reservationMainService.getMinMaxTime(item.getReserveId());
            reserveVo.setReserveTime(minMaxTime);

            return reserveVo;
        }).collect(Collectors.toList());

        return R.success(reserveList);
    }

    @GetMapping("/getReservationById")
    public R<ReserveVo> getReservationById(@RequestParam("reserveId")Integer reserveId){

        ReserveVo reserveVo = reservationMainService.getReservationById(reserveId);

        return R.success(reserveVo);
    }

    @PutMapping("/cancelReservation")
    public R<String> cancelReservation(@RequestParam("reserveId")Integer reserveId){

        LambdaUpdateWrapper<ReservationMain> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(ReservationMain::getReserveId,reserveId)
                .set(ReservationMain::getReserveStatus,2);

        reservationMainService.update(wrapper);

        return R.success("取消成功");
    }
}
